﻿using System;
using System.Reflection;
using System.Collections;

//using Gonte.ObjectModel;

namespace Gonte.Reflection
{
    /// <summary>
    ///  Traverses the public properties of an object and its children
    /// </summary>
    //public abstract class ObjectPropertiesTraversal
    //{

    //    #region Constructors

    //    public ObjectPropertiesTraversal()
    //    {
    //    } 

    //    #endregion

    //    #region Methods

    //    /// <summary>
    //    /// Traverses the public properties of an object and its children 
    //    /// </summary>
    //    /// <param name="@object">The object to traverse</param>
    //    protected void Traverse(Object @object)
    //    {
    //        try
    //        {
    //            if (!OnBeforeTraversal(@object))
    //            {
    //                return;
    //            }

    //            if (@object == null)
    //            {
    //                OnNullObject(ref @object);
    //                if (@object == null)
    //                {
    //                    return; // Nothing to traverse
    //                }
    //            }

    //            if (PrimitiveType.IsPrimitive(@object)
    //                || @object.GetType().IsEnum)
    //            {
    //                OnPrimitive(ref @object);
    //                return;  // Nothing to traverse
    //            }

    //            if (@object is ICollection)
    //            {
    //                OnBeforeCollection(ref @object);
    //                OnCollection(ref @object);
    //                OnAfterCollection(ref @object);
    //            }
    //            else
    //            {
    //                OnObject(ref @object);
    //            }
    //        }
    //        finally
    //        {
    //            OnAfterTraversal(@object);
    //        }
    //    }

    //    #endregion

    //    #region Properties

    //    /// <summary>
    //    /// The current parentInfo of the object being traversed
    //    /// </summary>
    //    public Object Parent
    //    {
    //        get { return parent_; }
    //        set { parent_ = value; }
    //    }

    //    /// <summary>
    //    /// The current propertyInfo info of the object being traversed
    //    /// </summary>
    //    public PropertyInfo PropertyInfo
    //    {
    //        get { return propertyInfo_; }
    //        set { propertyInfo_ = value; }
    //    }

    //    #endregion

    //    #region Overridables

    //    /// <summary>
    //    /// Called before traversing the object
    //    /// </summary>
    //    /// <param name="@object">The object to be traversed</param>
    //    /// <returns></returns>
    //    protected virtual bool OnBeforeTraversal(Object @object)
    //    {
    //        return true;
    //    } 

    //    /// <summary>
    //    /// Called when an object is null. This is the place to create the object if needed
    //    /// </summary>
    //    /// <param name="@object">The null object</param>
    //    protected virtual void OnNullObject(ref Object @object)
    //    {
    //    }

    //    /// <summary>
    //    /// Called when an object is a primitive as defined by the primitive attributeType classifier
    //    /// </summary>
    //    /// <param name="@object">The primitive object</param>
    //    protected virtual void OnPrimitive(ref Object @object)
    //    {
    //    }

    //    /// <summary>
    //    /// Called before processing a collection
    //    /// </summary>
    //    /// <param name="@object"></param>
    //    protected virtual void OnBeforeCollection(ref object @object)
    //    {
    //    }

    //    /// <summary>
    //    /// Called when the object is a collection
    //    /// </summary>
    //    /// <param name="@object">The collection object</param>
    //    protected virtual void OnCollection(ref Object @object)
    //    {
    //        Object parent = parent_; // Set the parent
    //        parent_ = @object;

    //        ICollection collection = @object as ICollection;
    //        foreach (Object item in collection)
    //        {
    //            Traverse(item);
    //        }

    //        parent_ = parent; // Restore the parentInfo
    //    }

    //    /// <summary>
    //    /// Called after finishing processing all the items of the collection
    //    /// </summary>
    //    /// <param name="@object"></param>
    //    protected virtual void OnAfterCollection(ref object @object)
    //    {
    //    }

    //    /// <summary>
    //    /// Called when the object is a non primitive one
    //    /// </summary>
    //    /// <param name="@object">The non primitive object</param>
    //    protected virtual void OnObject(ref Object @object)
    //    {
    //        Object parent = parent_; // Set the parentInfo
    //        parent_ = @object;

    //        PropertyInfo pi = propertyInfo_;

    //        Type type = @object.GetType();
    //        foreach (PropertyInfo propertyInfo in type.GetProperties())
    //        {
    //            propertyInfo_ = propertyInfo;
    //            Object value = propertyInfo.GetValue(@object, null);

    //            if (value == null)
    //            {
    //                OnNullObject(ref value);
    //                if (value == null)
    //                {
    //                    continue; // Nothing to traverse
    //                }
    //            }

    //            Traverse(value);
    //        };

    //        propertyInfo_ = pi; // Restore the current propertyInfo info
    //        parent_ = parent; // Restore the parentInfo
    //    }

    //    protected virtual void OnAfterTraversal(object @object)
    //    {
    //    }

    //    #endregion

    //    #region Fields

    //    protected Object parent_;
    //    protected PropertyInfo propertyInfo_;

    //    #endregion
    //}
}
